import java.awt.*;
import javax.swing.*;
import javax.swing.border.Border;
import javax.swing.border.MatteBorder;
import javax.swing.event.EventListenerList;

import CustomEventClass.JDateEvent;
import CustomEventClass.JDateEventListener;

import java.awt.event.*;
import java.util.*;


public class JDate extends JPanel{

	ArrayList<JButton> buttonList = new ArrayList<JButton>();
	protected EventListenerList listenerList = new EventListenerList();
	
	
	private JPanel datePanel = new JPanel(new GridLayout(7,7,2,2)); 
	private JPanel controlPanel = new JPanel();
	private JLabel  yearLabel;
	private JComboBox monthSelector;
	private JTextField yearField;
	
	static int year, month, date,lastDay, firstDayIndex;
	
	private JButton prevYear, prevMonth, nextMonth, nextYear;
	
	Calendar today = Calendar.getInstance();
	
	private final String[] monthArray = {"January","February","March","April","May","June","July","August","September","October","November","December"};
	
	JDate(){
	 
		Border blackline = BorderFactory.createLineBorder(Color.black);
		this.setLayout(new BorderLayout());
		this.dateInitializer();
		
		//--------Setting GUI Color/Border----------
		controlPanel.setBackground(Color.LIGHT_GRAY);
		controlPanel.setBorder(blackline);
		datePanel.setBackground(Color.white);
		datePanel.setBorder(blackline);
		
		this.setupControlPane();
		this.setupDateGrid();

		this.add(BorderLayout.NORTH,controlPanel);
		this.add(BorderLayout.CENTER, datePanel);
	}
	
	private void dateInitializer() {
		year = today.get(Calendar.YEAR);
		month = today.get(Calendar.MONTH);
		date = today.get(Calendar.DATE);
		today.set(year,month+1,0); //setting it to last day of the month
		lastDay = today.get(Calendar.DATE);
		today.set(year,month,1);
		firstDayIndex = today.get(Calendar.DAY_OF_WEEK);
		today.set(year,month,date);
		

	}
	
	private void setupDateGrid(){
	
		//-----------Adding Day Columns----------------
		JLabel sunLabel = new JLabel("SUN",JLabel.CENTER);
		sunLabel.setForeground(Color.RED);
		datePanel.add(sunLabel);
		
		datePanel.add(new JLabel("MON",JLabel.CENTER));
		datePanel.add(new JLabel("TUE",JLabel.CENTER));
		datePanel.add(new JLabel("WED",JLabel.CENTER));
		datePanel.add(new JLabel("THU",JLabel.CENTER));
		datePanel.add(new JLabel("FRI",JLabel.CENTER));
		
		JLabel satLabel = new JLabel("SAT",JLabel.CENTER);
		satLabel.setForeground(Color.BLUE);
		datePanel.add(satLabel);
		
		
		//-------Giving Spaces for Starting Day--------
		for (int k = 1; k < firstDayIndex; k++){
			datePanel.add(new JLabel());
		}
		
		buttonList.removeAll(buttonList);
		//-------------Adding Day Buttons---------------
		for (int i=1;i <= lastDay;i++){
			JButton btn = new JButton(new Integer(i).toString());
			btn.addActionListener(new DateButtonHandler());
			if (i == date){
				//skip
			}else{
				btn.setBackground(Color.white);
			}
			buttonList.add(btn);
			datePanel.add(buttonList.get(i-1));
		}
		
		
		//-------Fill up remaining area with JLabel-----
		for (int j = 1; j<=43-firstDayIndex-lastDay;j++){
			datePanel.add(new JLabel());
		}
	}
	private void setupControlPane(){
		prevYear = new JButton("<<");
		prevMonth = new JButton("<");
		nextMonth = new JButton(">");
		nextYear = new JButton(">>");
		
		monthSelector = new JComboBox<Object>(monthArray);
		monthSelector.setSelectedIndex(today.get(Calendar.MONTH));
		monthSelector.addItemListener(new MonthSelectorHandler());
		
		prevYear.addActionListener(new Handler());
		prevMonth.addActionListener(new Handler());
		nextMonth.addActionListener(new Handler());
		nextYear.addActionListener(new Handler());
		
		yearLabel = new JLabel("    "+ new Integer(year).toString()+ "   ",JLabel.CENTER );
		yearLabel.setBackground(Color.white);
		controlPanel.add(prevYear);
		controlPanel.add(prevMonth);
		controlPanel.add(yearLabel);
		controlPanel.add(monthSelector);
		controlPanel.add(nextMonth);
		controlPanel.add(nextYear);
	}
	
	private class Handler implements ActionListener{
		public void actionPerformed(ActionEvent ev) {
			if (ev.getSource().equals(prevYear)){
				today.add(Calendar.YEAR, -1);
			}else if(ev.getSource().equals(prevMonth)){
				today.add(Calendar.MONTH, -1);
			}else if(ev.getSource().equals(nextMonth)){
				today.add(Calendar.MONTH, +1);
			}else if(ev.getSource().equals(nextYear)){
				today.add(Calendar.YEAR, +1);
			}
			
			dateInitializer();
			fireJDateEvent(new JDateEvent(this, JDateEvent.MONTH));
			
			monthSelector.setSelectedIndex(today.get(Calendar.MONTH));
			datePanel.removeAll();
			yearLabel.setText("    " + new Integer(year).toString() + "   ");
			setupDateGrid();
			validate();
		}		
	}
	
	private class MonthSelectorHandler implements ItemListener{
		public void itemStateChanged(ItemEvent ev) {
				int tempIndex = monthSelector.getSelectedIndex();
				today.set(year, tempIndex, date);
				datePanel.removeAll();
				yearLabel.setText("    "+ new Integer(year).toString()+ "   ");
				dateInitializer();	
				fireJDateEvent(new JDateEvent(this, JDateEvent.MONTH));
			
				setupDateGrid();
				validate();
		}
	}
	
	private class DateButtonHandler implements ActionListener{
		public void actionPerformed(ActionEvent ev) {
				int selIndex = Integer.parseInt((((JButton) ev.getSource()).getText()));
				today.set(year,month,selIndex);
				datePanel.removeAll();
				dateInitializer();
				fireJDateEvent(new JDateEvent(this, JDateEvent.DAY));
				setupDateGrid();
				validate();				
		}		
	}
	
	public String getDate(){
		return year +"-" + ((month+1<10)? "0"+(month+1):month+1) + "-" + ((date<10)?"0" + date:date);		
	}
	
	public Calendar getCalendarVar(){
		return today;
	}
	//////////////////////////////////////////////////////////////////////////////
	 public void addJDateEventListener(JDateEventListener listener) {  
	        listenerList.add(JDateEventListener.class, listener);
	 }
	 public void removeJDateEventListener(JDateEventListener listener) {  
	        listenerList.remove(JDateEventListener.class, listener);  
	 }  
	 
	 private void fireJDateEvent(JDateEvent event) {  
	        Object[] listeners = listenerList.getListenerList();  
	  
	        for (int i = listeners.length-2; i>=0; i-=2) {  
	            if (listeners[i] == JDateEventListener.class) {  
	                ((JDateEventListener)listeners[i+1]).dateEventHandler(event);  
	            }  
	     }  
	 }
	 //////////////////////////////////////////////////////////////////////////////

}
